#pragma once
#include <vector>
#include <deque>
#include <conio.h>
#include <mutex>
#include "Player.h"
#include <map>
#include <thread>


using namespace std;



class Game
{
private:
        vector<vector<char>> matrix;
        int matrixSize;
        deque<char> *pQueue1;
        deque<char> *pQueue2;
        deque<Pos> *gQueue;
        char *c;
public:

        Game()
        {
        }

        Game(int size, deque<Pos> &gQueue, deque<char> &pQueue1, deque<char> &pQueue2)
        {
                matrixSize = size;
                matrix = vector<vector<char>>(size);
                for (int i = 0; i < size; i++)
                {
                        matrix[i] = vector<char>(size);
                }
                for (int r = 0; r < matrixSize; r++)
                {
                        for (int c = 0; c < matrixSize; c++)
                                matrix[r][c] = '-';
                }
                this->pQueue1 = &pQueue1;
                this->pQueue2 = &pQueue2;
                this->gQueue = &gQueue;
        }

        void upDateMatrix()
        {
                Pos position;

                mtx_gQue.lock();
                if (!gQueue->empty())
                {
                        position = gQueue->front();
                        gQueue->pop_front();

                        for (int r = 0; r < matrixSize; r++)
                        {
                                for (int c = 0; c < matrixSize; c++)
                                if (matrix[r][c] == position.id)
                                {
                                        matrix[r][c] = '-';
                                }
                        }
                        int x = position.xCoord;
                        int y = position.yCoord;
                        matrix[y][x] = position.id;
                }

                mtx_gQue.unlock();
        }

        void PushQueue(char c)
        {
                //char c = _getch();
                mtx_pQue.lock();
                if (c == 'a' || c == 'w' || c == 's' || c == 'd')
                        pQueue1->push_back(c);
                if (c == 'i' || c == 'j' || c == 'k' || c == 'l')
                        pQueue2->push_back(c);
                mtx_pQue.unlock();
        }

        void operator()()
        {
                char c = 'z';
                if (_kbhit()!= 0)
                {
                        c = _getch();
                }

                while (c != 'q')
                {
                        draw();
                        PushQueue(c);
                        c = ' ';
                        upDateMatrix();
                        this_thread::sleep_for(chrono::milliseconds(100));
                        if (_kbhit()!= 0)
                        {
                                c = _getch();
                        }
                }
        }

        void draw()
        {
                system("cls");
                for (int r = 0; r < matrixSize; r++)
                {
                        for (int c = 0; c < matrixSize; c++)
                        {
                                cout << (char)matrix[r][c] << "  ";
                        }
                        cout << endl << endl;
                }
        }

        ~Game()
        {
        }
};